using System;
using System.Collections.Generic;
using WiMo.Games.Physics;

namespace WiMo.Games.Drawables
{
    public enum CollisionShapes
    {
        Sphere,
        SphereList,
        Rectangle,
        LineList,
    }

    public enum CollisionManagement
    {
        Auto,
        Manual
    }

    public class CollisionSphere
    {
        public Vector2 RelativeOrigin { get; set; }
        public float Radius { get; set; }
    }

    public interface ICollidable : IPositionable
    {
        /// <summary>
        /// Will fire when the object collides with another object.
        /// </summary>
        event EventHandler<CollisionEventArgs> Collision;
        /// <summary>
        /// Will fire when an object that previously collided with another
        /// object seperates.
        /// </summary>
        event EventHandler<CollisionEventArgs> Seperation;

        /// <summary>
        /// The CoefRestitution will determine the elaticity of the object
        /// when it collides with something.  A CoefRestituion of 1 means that 
        /// none of the force will be lost in the collision (think a rubber ball that bounces perfectly)
        /// 
        /// A CoefRestituion of 0 means that all of the force will be lost.  Think a soft ball of clay that does not
        /// bounce at all.
        /// </summary>
        float CoefRestitution { get; set; }

        bool CheckForCollision(ISprite sprite);
        CollisionCategory CollisionCategory { get; set; }
        void CollideWithBorder(CollisionEventArgs.Border border);
        /// <summary>
        /// Add a list of collision categories to this list.
        /// </summary>
        List<CollisionCategory> CanCollidesWithList { get; }
        List<ICollidable> CollisionList { get; }
        void OnCollide(CollisionEventArgs args);
        void OnSeperation(CollisionEventArgs args);
        CollisionShapes CollisionShape {get; set;}
        IGeometry Geometry { get; }
        List<CollisionSphere> CollisionSpheres { get; set; }

        /// <summary>
        /// If this is set to Auto, the physics engine will figure out
        /// what force should happen upon collision based upon the angle,
        /// mass and velocity.
        /// 
        /// If this is set to Manual, you will just receive the event 
        /// and you will be responsible for applying any forces to seperate
        /// the spheres.
        /// </summary>
        CollisionManagement CollisionManagement { get; set; }

        /// <summary>
        /// The sprite should be able to build a set of points to be used for 
        /// collision detection relative to the origin of the sprite.  The 
        /// end-application shouldn't need to calculate this.
        /// </summary>
        List<Location> CollisionDetectionPoints { get; set; }

        /// <summary>
        /// Provides access to the collision manager.
        /// </summary>
        ICollisionManager CollisionManager { get; set; }


        Vector2 GetDistance(ISprite sprite);
    }

}
